package database;

import utils.StrUtils;

/**
 * Clause.java
 * Cette classe gere la modelisation (simplifiee) d'une clause logique
 * @author Aubry Pirian
 * @version 1.0
 */
public class Clause {

	private String operator;		// Operateur
	private Attribute attribute;	// Clause simple (sans operateur)
	private Clause left;			// Clause a gauche de l'operateur binaire
	private Clause right;			// Clause a droite de l'operateur (unaire ou binaire)
	
	/**
	 * Operteurs autorises
	 */
	final static String[][] OPERATORS = {
		{"not"},		// Unaires
		{"and","or"}	// Binaires
	};
	
	/**
	 * Constructeur de clause simple (sans operateur)
	 * @throws NoSuchFieldException : attribut non valide
	 */
	public Clause (ValuedAttribute attribute) throws NoSuchFieldException {
		if ( attribute==null ) throw new NoSuchFieldException("Attribut non valide.");
		this.attribute = attribute;
		this.operator = null;
		this.left = null;
		this.right = null;
	}
	
	/**
	 * Constructeur de Clause avec opérateur unaire
	 */
	public Clause (String operator, Clause clause) throws NoSuchFieldException {
		if ( !StrUtils.inArray(OPERATORS[0],operator,false) )
			throw new NoSuchFieldException("Opérateur non unaire.");
		if ( clause==null) 
			throw new NoSuchFieldException("Clause manquante.");
		this.operator = operator;
		this.attribute = null;
		this.left = null;
		this.right = clause;
	}
	
	/**
	 * Constructeur de Clause
	 */
	public Clause (String operator, Clause left, Clause right) throws NoSuchFieldException {
		this.operator = operator;
		this.attribute = null;
		switch (isOperator(operator)) {
			case 1:
				// operateur unaire
				this.left = null;
			break;
			case 2:
				// operateur binaire
				if (left==null) throw new NoSuchFieldException("Clause gauche manquante.");
				this.left = left;
			break;
			default: throw new NoSuchFieldException("Opérateur inconnu.");
		}
		if (right==null) throw new NoSuchFieldException("Clause droite manquante.");
		this.right=right;
	}
	
	/**
	 * int isOperator(String op)
	 * Cherche l'operateur 'op' dans operators
	 * @return
	 * . 1 s'il est unaire
	 * . 2 s'il est binaire
	 * . 0 s'il n'existe pas
	 */
	private static int isOperator(String op) {
		if (StrUtils.inArray(OPERATORS[0],op,false)) return 1;
		if (StrUtils.inArray(OPERATORS[1],op,false)) return 2;
		return 0;
	}

	/**
	 * Methode d'affichage
	 */
	public String toString () {
		// Clause sans operateur :
		if (this.operator==null) return this.attribute.toString();
		// Clause avec operateur :
		switch (Clause.isOperator(this.operator)) {
			// Clause avec operateur unaire :
			case 1:return "NOT "+this.right;
			// Clause avec operateur biaire :
			case 2: return this.left+" "+this.operator+" "+this.right;
			// Autres...
			default: return "";
		}
	}
	
	

}
